package v1

import (
	"common"
	"common/biz"
	"common/config"
	"common/jwts"
	"common/logs"
	"common/rpc"
	"context"
	"core/dao"
	"core/models/entity"
	"core/repo"
	"encoding/json"
	"framework/msError"
	"gate/internal/tool"
	"gate/types/wxtypes"
	"strconv"
	"time"
	"user/pb"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"gorm.io/gorm"
)

type WxApi struct {
	GOrm    *gorm.DB
	GameDao *dao.GameDao
}

func NewWxApi(repo *repo.Manager) *WxApi {
	return &WxApi{
		GOrm:    repo.Mysql.GOrm,
		GameDao: dao.NewGameDao(repo),
	}
}
func (w *WxApi) Wxautologin(ctx *gin.Context) {
	var req pb.WxAutologinParams
	err2 := ctx.ShouldBindJSON(&req)
	if err2 != nil {
		logs.Error("err2:%v", err2)
		common.Fail(ctx, biz.RequestDataError)
		return
	}

	req.Ip = tool.GetClientIP(ctx)
	// 注册
	response, err := rpc.UserRpcClient.WxAutoLogin(context.TODO(), &req)
	if err != nil {
		logs.Error("userRpc Request err:%v", err)
		common.Fail(ctx, msError.ToError(err))
		return
	}
	clians := jwts.CustomClaims{
		Uid: response.Uid,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(7 * 24 * time.Hour)),
		},
	}
	token, err := jwts.GenToken(&clians, config.Conf.Jwt.Secret)
	if err != nil {
		logs.Error("Register jwt gen token err:%v", err)
	}
	result := map[string]any{
		"openid": response.Openid,
		"uid":    response.Uid,
		"token":  token,
	}
	common.Success(ctx, result)
}

func (w *WxApi) Wxrankinfo(ctx *gin.Context) {
	var req wxtypes.RankInfoParams
	err2 := ctx.ShouldBindJSON(&req)
	if err2 != nil {
		logs.Error("err2:%v", err2)
		common.Fail(ctx, biz.RequestDataError)
		return
	}
	//  排行榜数据为空也不行
	if len(req.RankInfo) == 0 {
		common.Fail(ctx, biz.NonRankInfo)
		return
	}

	uid := ctx.Keys["uid"].(string)
	//查询用户信息
	userAcc, err := w.getUserInfoByuid(req.GId, uid)
	if err != nil {
		common.Fail(ctx, biz.InvalidUsers)
		return
	}
	uidInt64, err := strconv.ParseInt(uid, 10, 64)
	if err != nil {
		logs.Fatal("ParseInt err%v", err)
		return
	}
	// var friend *entity.WxFriendModel
	var where map[string]any
	for _, info := range req.RankInfo {
		kvD, _ := json.Marshal(info.KVData)
		where = map[string]any{
			"gid":           req.GId,
			"openid":        userAcc.WxOpenid,
			"uid":           uidInt64,
			"friend_openid": info.Openid,
			"friend_uid":    0,
		}
		friend := &entity.WxFriendModel{
			Uid:             uidInt64,
			Gid:             req.GId,
			Openid:          userAcc.WxOpenid,
			FriendAvatarUrl: info.AvatarUrl,
			FriendKvdata:    string(kvD),
			FriendNickName:  info.Nickname,
			FriendOpenid:    info.Openid,
			FriendUid:       0, // 根据实际情况调整
		}

		// 尝试根据条件查找或创建记录
		result := w.GOrm.Where(where).FirstOrCreate(friend)
		if result.RowsAffected == 0 {
			friend.ID = 0
			updateResult := w.GOrm.Model(friend).Where(where).Updates(map[string]interface{}{
				"friend_nickname":   info.Nickname,
				"friend_avatar_url": info.AvatarUrl,
				"friend_kvdata":     string(kvD),
			})
			// 检查更新结果
			if updateResult.Error != nil {
				logs.Error("更新失败:", updateResult.Error)
			} else {
				logs.Debug("更新结果, RowsAffected=", updateResult.RowsAffected)
			}
		}

	}

	common.Success(ctx, nil)

}

func (w *WxApi) getUserInfoByuid(gid int64, uid string) (*entity.User, error) {
	var user *entity.User
	err := w.GOrm.Where("ID=?", uid).Where("gid=?", gid).Find(&user).Error
	if err != nil {
		return nil, err
	}
	return user, nil
}

/**
 * 事件上报
 */
func (w *WxApi) Event(ctx *gin.Context) {
	// 接收传入参数
	var req wxtypes.EventLogParam
	err2 := ctx.ShouldBindJSON(&req)
	if err2 != nil {
		logs.Error("err2:%v", err2)
		common.Fail(ctx, biz.RequestDataError)
		return
	}
	uid := ctx.Keys["uid"].(string)
	//查询用户信息
	userAcc, err := w.getUserInfoByuid(req.GId, uid)
	if err != nil || userAcc.ID == 0 {
		common.Fail(ctx, biz.InvalidUsers)
		return
	}
	uidInt64, err := strconv.ParseInt(uid, 10, 64)
	if err != nil {
		logs.Fatal("ParseInt err%v", err)
		return
	}
	ip := tool.GetClientIP(ctx)
	nowDate, _ := strconv.ParseInt(time.Now().Format("20060102"), 10, 64)
	nowDateH, _ := strconv.ParseInt(time.Now().Format("2006010215"), 10, 64)
	eventLog := &entity.EventLog{
		Uid:       uidInt64,
		Event:     req.Event,
		EventDate: nowDate,
		EventH:    nowDateH,
		EventTime: time.Now().Unix(),
		Gid:       req.GId,
		Account:   userAcc.Account,
		RegTIme:   userAcc.RegTIme,
		RegDate:   userAcc.RegDate,
		Ip:        ip,
		Province:  "",
		City:      "",
		Dsid:      "",
		Drid:      req.Drid,
		Drname:    req.Drname,
		Drlevel:   req.Drlevel,
		Ua:        ctx.GetHeader("User-Agent"),
	}
	// 写入mongo
	w.GameDao.SaveEventLog(ctx, eventLog)
	common.Success(ctx, nil)
}
